package com.woniu.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniu.user.controller.form.SearchForm;
import com.woniu.user.exception.WebException;
import com.woniu.user.exception.WebExceptionCode;
import com.woniu.user.model.*;
import com.woniu.user.dao.BookDao;
import com.woniu.user.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 预约信息表 服务实现类
 * </p>
 *
 * @author Silas
 * @since 2023-02-15
 */
@Service
@Slf4j
public class BookServiceImpl extends ServiceImpl<BookDao, Book> implements BookService {
    @Resource
    private BookDao bookDao;
    @Resource
    private OrderService orderService;
    @Resource
    private OccupyService occupyService;
    @Resource
    private RocketMQTemplate mqTemplate;
    @Resource
    private NoticeService noticeService;
    @Resource
    private AccountService accountService;
    @Resource
    private CoachService coachService;

    @Override
    public IPage<Book> searchMy(String condition, Integer userId, Integer current, Integer size) {
        Integer coachId = coachService.getOne(new QueryWrapper<Coach>().eq("account_id", userId)).getCoachId();
        IPage<Book> page = new Page<>(current == null ? 1 : current, size == null ? 4 : size);
        QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("coach_id", coachId);
        if (!("".equals(condition) || condition == null)) {
            queryWrapper.eq("state", condition)
                    .or().like("user_name", condition)
                    .or().like("no", condition)
                    .or().like("user_name", condition)
                    .or().like("lesson_name", condition);
        }
        IPage<Book> bookPage = bookDao.selectPage(page, queryWrapper);
        return bookPage;
    }

    @Override
    public void refuse(Integer bookId, String message) {
        Book book = getById(bookId);
        book.setState("不同意");
        book.setFinishTime(LocalDateTime.now());
        updateById(book);

        // 将occupy表中的状态置为失效
        Integer occupyId = book.getOccupyId();
        occupyService.cancelOccupy(occupyId);

        // 给用户发信息notice（准备内容）
        Integer coachId = book.getCoachId();
        String coachName = book.getCoachName();
        Integer userId = book.getUserId();
        String userName = book.getUserName();
        String title = "您的预约未成功 详见消息详情";
        String email = accountService.getUserEmailById(userId);

        // 生成消息体发送到mq
        String[] param = {email, title, message};
        SendResult sendResult = mqTemplate.syncSend("notice-topic", param);
        log.info(sendResult.toString());

        // 生成notice中写入该条信息
        Notice notice = new Notice();
        notice.setCoachId(coachId);
        notice.setCoachName(coachName);
        notice.setUserId(userId);
        notice.setUserName(userName);
        notice.setSendTime(LocalDateTime.now());
        notice.setMessage(message);
        noticeService.save(notice);
    }

    @Override
    public void access(Integer bookId) {
        Book book = getById(bookId);
        book.setFinishTime(LocalDateTime.now());
        book.setState("同意");
        updateById(book);
        orderService.createOrder(book);// 创建订单

        // 给学员发消息
        Integer coachId = book.getCoachId();
        String coachName = book.getCoachName();
        Integer userId = book.getUserId();
        String userName = book.getUserName();
        String title = "您的预约已同意";
        String email = accountService.getUserEmailById(userId);
        String message = "您的专属私教已同意了您的预约，已生成订单，请前往支付。";

        // 生成消息体发送到mq
        String[] param = {email, title, message};
        SendResult sendResult = mqTemplate.syncSend("notice-topic", param);
        log.info(sendResult.toString());

        // 生成notice中写入该条信息
        Notice notice = new Notice();
        notice.setCoachId(coachId);
        notice.setCoachName(coachName);
        notice.setUserId(userId);
        notice.setUserName(userName);
        notice.setSendTime(LocalDateTime.now());
        notice.setMessage(message);
        noticeService.save(notice);
    }

    @Override
    public List<Book> find(String date) {
        List<Book> bookList = bookDao.selectList(new QueryWrapper<Book>().eq("create_time", date));
        return bookList;
    }

    // 查看我的预约单
    @Override
    public IPage<Book> getMyBook(Integer userId, Page<Book> bookPage) {
        return this.baseMapper.selectPage(bookPage, new QueryWrapper<Book>().eq("user_id", userId).orderByDesc("book_id"));
    }

    // 用户取消预约
    @Override
    public void del(Integer bookId, Integer userId) {
        // 获取用户
        Account account = accountService.getById(userId);
        if (account == null) throw new WebException(WebExceptionCode.USER_IS_NOT_EXISTS);
        Book book = this.getById(bookId);
        if (book == null) throw new WebException(WebExceptionCode.BOOK_IS_NOT_EXISTS);
        this.removeById(bookId);// 移除预约单
        // 移除时间占用
        LocalDateTime lessonTime = book.getLessonTime();
        Integer coachId = book.getCoachId();
        boolean flag = occupyService.remove(new UpdateWrapper<Occupy>().eq("time", lessonTime).eq("user_id", userId).eq("coach_id", coachId));
        if(!flag) throw new WebException(WebExceptionCode.OCCUPY_ERROR);
    }

    // 用户搜索
    @Override
    public IPage<Book> search(SearchForm form, Integer userId) {
        Account account = accountService.getById(userId);
        if (account == null) throw new WebException(WebExceptionCode.USER_IS_NOT_EXISTS);
        Integer page = form.getPage();
        Integer size = form.getSize();
        String key = form.getKey();
        Page<Book> bookPage = new Page<>(page, size);
        QueryWrapper<Book> wrapper = new QueryWrapper<Book>().eq("user_id", userId);
        wrapper.like("no", key).or().like("coach_name", key).or().like("lesson_name", key).or().like("state", key);
        return this.baseMapper.selectPage(bookPage, wrapper);
    }
}
